home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Spicy Pics!
/
Spicy Pics!.iso
/
amiga
/
gifmachn
/
sources
/
24to12.c
next >
Wrap
C/C++ Source or Header
|
1991-09-18
|
4KB
|
184 lines
/* Copyright 1990 by Christopher A. Wichura.
See file GIFMachine.doc for full description of rights.
*/
#include "GIFMachine.h"
extern struct GIFdescriptor gdesc;
EXTERNBITPLANE;
extern BOOL DisplayCounts;
/* since both MasterColourTable and the PaletteBuf are the same size and
type we will define MCT to be the PaletteBuf to cut down on static
memory declarations */
#define MasterColourTable PaletteBuf
extern UBYTE MasterColourTable[MAXCOLOURS];
static UWORD TotalColours;
extern BYTE *CurrentLineErr[3];
extern BYTE *LastLineErr[3];
extern char *AbortMsg;
#define MAXERR 2
void ReduceTo12(void)
{
register UWORD x;
register UWORD y;
PutStr("...Reducing palette to 12 bits.\n......");
if (DisplayCounts)
PutStr("Line ");
else
PutStr("Working");
Flush(Output());
TotalColours = 0;
memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
for (y = 0; y < gdesc.gd_Height; y++) {
if (DisplayCounts)
MyPrintf("%5ld", y);
if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
MyPrintf("\n%s", AbortMsg);
MyExit(ABORTEXITVAL);
}
for (x = 0; x < gdesc.gd_Width; x++)
PutValue(x, y, AddColour(&BitPlane[y][x]));
if (DisplayCounts)
PutStr("\x1B[5D");
}
MyPrintf("\x1B[%ldD%ld total unique colours used.\n", (DisplayCounts ? 5 : 7), TotalColours);
}
void DitherTo12(void)
{
register UWORD x;
register UWORD y;
register int RedErr;
register int GreenErr;
register int BlueErr;
BYTE **cerr, **lerr, **terr;
struct RGB rgb;
PutStr("...Dithering palette to 12 bits.\n......Setup");
Flush(Output());
TotalColours = 0;
memset((char *)MasterColourTable, 0, sizeof(MasterColourTable));
cerr = (BYTE **)&CurrentLineErr[0];
lerr = (BYTE **)&LastLineErr[0];
/* the top, left and right borders will be used unmodified */
for (x = 0; x < gdesc.gd_Width; x++)
PutValue(x, 0, AddColour(&BitPlane[0][x]));
for (y = 1; y < gdesc.gd_Height; y++) {
PutValue(0, y, AddColour(&BitPlane[y][0]));
PutValue(gdesc.gd_Width - 1, y, AddColour(&BitPlane[y][gdesc.gd_Width - 1]));
}
/* since the error tables are alloced with MEMF_CLEAR we won't bother
to clear them here. instead, we just hit the main loop */
if (DisplayCounts)
PutStr("\x1B[5DLine ");
else
PutStr("\x1B[5DWorking");
Flush(Output());
for (y = 1; y < gdesc.gd_Height; y++) {
if (DisplayCounts)
MyPrintf("%5ld", y);
if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
MyPrintf("\n%s", AbortMsg);
MyExit(ABORTEXITVAL);
}
for (x = 1; x < (gdesc.gd_Width - 1); x++) {
rgb = BitPlane[y][x];
RedErr = cerr[0][x - 1] + 7*lerr[0][x - 1] + 5*lerr[0][x] + 3*lerr[0][x + 1];
GreenErr = cerr[1][x - 1] + 7*lerr[1][x - 1] + 5*lerr[1][x] + 3*lerr[1][x + 1];
BlueErr = cerr[2][x - 1] + 7*lerr[2][x - 1] + 5*lerr[2][x] + 3*lerr[2][x + 1];
RedErr >>= 4;
GreenErr >>= 4;
BlueErr >>= 4;
/* now we add the errors into the colour we want. if this would push
us over 255 (and thus out of range) we subtract the error out so
that we still see some dithering instead of washing out the area. */
if (rgb.rgb_Red + RedErr > 255)
rgb.rgb_Red -= RedErr;
else
rgb.rgb_Red += RedErr;
if (rgb.rgb_Green + GreenErr > 255)
rgb.rgb_Green -= GreenErr;
else
rgb.rgb_Green += GreenErr;
if (rgb.rgb_Blue + BlueErr > 255)
rgb.rgb_Blue -= BlueErr;
else
rgb.rgb_Blue += BlueErr;
PutValue(x, y, AddColour(&rgb));
RedErr = (int)rgb.rgb_Red - (int)(rgb.rgb_Red & 0xF0);
GreenErr = (int)rgb.rgb_Green - (int)(rgb.rgb_Green & 0xF0);
BlueErr = (int)rgb.rgb_Blue - (int)(rgb.rgb_Blue & 0xF0);
if (RedErr > MAXERR)
RedErr = (RedErr * 3) >> 2;
if (GreenErr > MAXERR)
GreenErr = (GreenErr * 3) >> 2;
if (BlueErr > MAXERR)
BlueErr = (BlueErr * 3) >> 2;
cerr[0][x] = RedErr;
cerr[1][x] = GreenErr;
cerr[2][x] = BlueErr;
}
terr = lerr;
lerr = cerr;
cerr = terr;
if (DisplayCounts)
PutStr("\x1B[5D");
}
MyPrintf("\x1B[%ldD%ld total unique colours used.\n", (DisplayCounts ? 5 : 7), TotalColours);
}
UWORD AddColour(struct RGB *rgb)
{
register UWORD colour;
colour = ((rgb->rgb_Red << 4) & 0xF00) |
(rgb->rgb_Green & 0xF0) |
(rgb->rgb_Blue >> 4);
if (!MasterColourTable[colour]) {
MasterColourTable[colour] = 1;
TotalColours++;
}
return colour;
}